import pandas as pd
import numpy as np
import matplotlib
matplotlib.use('Agg')  # 在导入plt之前设置为非交互式后端,否则plt.figure会报Tcl/Tk错误
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties  # 处理中文显示
import seaborn as sns

class AreaAnalysis:
    def __init__(self, level_info):

        self.level_info = level_info

        # 设置绘图风格
        # plt.style.use('seaborn')
        # plt.style.use('seaborn-v0_8') 
        # plt.style.use('ggplot') 
        sns.set_style("whitegrid")

        # 字体设置
        # self.font = FontProperties(family='SimHei')  # 简体中文黑体
        # 设置中文字体，使用下载的字体
        # self.font = FontProperties(fname=r'path/to/SimHei.ttf')
        self.setup_font()

        # 图表全局设置
        plt.rcParams.update({
            'figure.dpi': 300,
            'figure.autolayout': True,
            'axes.unicode_minus': False,
            'axes.grid': True,
            'grid.alpha': 0.3,
            'grid.linestyle': '--'
        })

    # 更完整的字体设置
    def setup_font(self):
        # 检查系统中可用的字体
        from matplotlib.font_manager import FontManager
        fm = FontManager()
        system_fonts = set(f.name for f in fm.ttflist)
        
        # 优先使用的字体列表
        preferred_fonts = [
            'Microsoft YaHei',
            'SimHei',
            'SimSun',
            'PingFang SC',
            'Heiti TC'
        ]
        
        # 选择第一个可用的字体
        for font in preferred_fonts:
            if font in system_fonts:
                self.font = FontProperties(family=font)
                plt.rcParams['font.sans-serif'] = [font] + plt.rcParams['font.sans-serif']
                break

    # 将省市区的数据转换为DataFrame格式，字段包括name,code,level,parent_code
    def create_dataframe(self):
        """将层级数据转换为DataFrame格式"""
        data = []
        for province in self.level_info:
            # 省级数据
            province_row = {
                'name': province['cName'],
                'code': province['code'],
                'level': '省级',
                'parent_code': None
            }
            data.append(province_row)
            
            # 市级数据
            for city in province.get('cityList', []):
                city_row = {
                    'name': city['cName'],
                    'code': city['code'],
                    'level': '市级',
                    'parent_code': province['code']
                }
                data.append(city_row)
                
                # 区县级数据
                for district in city.get('districtList', []):
                    district_row = {
                        'name': district['cName'],
                        'code': district['code'],
                        'level': '区县级',
                        'parent_code': city['code']
                    }
                    data.append(district_row)
                    
        return pd.DataFrame(data)
        
    def analyze_area_distribution(self):
        """分析各级行政区划分布"""
        df = self.create_dataframe()
        level_counts = df['level'].value_counts()
        
        # 创建图形和轴对象
        # plt.figure(figsize=(10, 6))
        fig,ax = plt.subplots(
            figsize=(10, 6), # 指定图形大小
            )

        # 创建x轴位置数组
        x_pos = np.arange(len(level_counts))

        # 绘制柱状图
        bars = ax.bar(
            x_pos,                    # x轴位置
            level_counts.values,      # y轴值
            color='skyblue',
            alpha=0.7
        ) 
        # 设置x轴刻度和标签
        ax.set_xticks(x_pos)
        ax.set_xticklabels(
            level_counts.index,       # 使用索引作为标签
            rotation=45, # 旋转45度
            fontproperties=self.font
        )      

        # 设置标题和标签
        plt.title('各级行政区数量分布', fontproperties=self.font)
        plt.xlabel('行政级别', fontproperties=self.font)
        plt.ylabel('数量', fontproperties=self.font)

        # 添加数值标签
        for i, v in enumerate(level_counts):
            ax.text(
                i,              # x位置
                v,              # y位置
                f'{v:,d}',     # 格式化数字
                ha='center',    # 水平居中
                va='bottom',    # 垂直对齐到底部
                fontproperties=self.font
            )

        # 调整布局
        plt.tight_layout()

        # 保存图形
        plt.savefig('area_distribution.png',dpi=300,bbox_inches='tight')
        plt.close()
        
        return level_counts
        
    def analyze_province_cities(self):
        """分析各省市级单位数量"""
        df = self.create_dataframe()
        
        # 统计每个省的市级单位数量
        province_cities = df[df['level']=='市级'].groupby('parent_code').size()
        province_names = df[df['level']=='省级'].set_index('code')['name']
        province_cities.index = province_cities.index.map(lambda x: province_names[x])
        
        # 对数据进行排序
        province_cities = province_cities.sort_values(ascending=True)  # 从小到大排序
        # 或者 province_cities = province_cities.sort_values(ascending=False)  # 从大到小排序
        
        # 创建图形和轴对象
        fig, ax = plt.subplots(figsize=(12, 8))
        
        # 创建位置数组
        x_pos = np.arange(len(province_cities))
        
        # 绘制水平条形图
        bars = ax.barh(
            x_pos,
            province_cities.values,
            color='skyblue',
            alpha=0.7
        )
        
        # 设置y轴刻度和标签
        ax.set_yticks(x_pos)
        ax.set_yticklabels(
            province_cities.index,
            fontproperties=self.font
        )
        
        # 设置标题和标签
        ax.set_title('各省市级单位数量', fontproperties=self.font, pad=20)
        ax.set_xlabel('市级单位数量', fontproperties=self.font, labelpad=10)
        ax.set_ylabel('省份', fontproperties=self.font, labelpad=10)
        
        # 添加数值标签
        for i, v in enumerate(province_cities):
            ax.text(
                v + 0.1,           # 稍微向右偏移
                i,
                f'{v:,d}',
                ha='left',
                va='center',
                fontproperties=self.font
            )
        
        # 添加网格线
        ax.grid(True, axis='x', linestyle='--', alpha=0.3)
        
        # 移除顶部和右侧边框
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        
        # 调整布局
        fig.tight_layout()
        
        # 保存图形
        fig.savefig(
            'province_cities.png',
            dpi=300,
            bbox_inches='tight',
            facecolor='white',
            edgecolor='none'
        )
        plt.close(fig)
        
        return province_cities
        
    def analyze_name_patterns(self):
        """分析地名特征"""
        df = self.create_dataframe()
        
        # 提取地名后缀
        def get_suffix(name):
            suffixes = ['省', '市', '区', '县', '自治区', '自治州']
            for suffix in suffixes:
                if name.endswith(suffix):
                    return suffix
            return '其他'
            
        df['suffix'] = df['name'].apply(get_suffix)
        
        # 统计不同后缀的数量并排序
        suffix_counts = df['suffix'].value_counts().sort_values(ascending=False)
        
        # 创建图形和轴对象
        fig, ax = plt.subplots(figsize=(12, 8))
        
        # 设置颜色
        colors = plt.cm.Pastel1(np.linspace(0, 1, len(suffix_counts)))
        
        # 绘制饼图
        wedges, texts, autotexts = ax.pie(
            suffix_counts,
            labels=suffix_counts.index,
            autopct='%1.1f%%',
            colors=colors,
            startangle=90,         # 起始角度
            pctdistance=0.85,      # 百分比标签位置
            wedgeprops=dict(
                width=0.5,         # 设置环形图的宽度
                edgecolor='white'  # 设置边框颜色
            )
        )
        
        # 设置标签文本
        plt.setp(texts, fontproperties=self.font, size=10)
        plt.setp(autotexts, size=9, weight='bold')
        
        # 添加图例
        legend_labels = [
            f'{suffix}: {count:,d}个' 
            for suffix, count in suffix_counts.items()
        ]
        
        ax.legend(
            wedges,
            legend_labels,
            title="地名后缀统计",
            loc="center left",
            bbox_to_anchor=(1, 0, 0.5, 1),
            prop=self.font
        )
        
        # 设置标题
        plt.title(
            '地名后缀分布',
            fontproperties=self.font,
            pad=20,
            size=14
        )
        
        # 添加总计信息
        total = suffix_counts.sum()
        plt.text(
            -1.5, -1.2,
            f'总计: {total:,d}个地名',
            fontproperties=self.font,
            ha='left',
            va='center'
        )
        
        # 调整布局
        plt.tight_layout()
        
        # 保存图形
        plt.savefig(
            'name_patterns.png',
            dpi=300,
            bbox_inches='tight',
            facecolor='white',
            edgecolor='none'
        )
        plt.close()
        
        return suffix_counts
        
    def generate_report(self):
        """生成数据分析报告"""
        level_counts = self.analyze_area_distribution()
        province_cities = self.analyze_province_cities()
        suffix_counts = self.analyze_name_patterns()
        
        # 使用f-string格式化字符串
        report = f"""
        地址数据分析报告
        
        1. 行政区划层级分布:
        {level_counts.to_string()}
        
        2. 各省市级单位数量:
        {province_cities.to_string()}
        
        3. 地名后缀分布:
        {suffix_counts.to_string()}
        """
        
        with open('area_analysis_report.txt', 'w', encoding='utf-8') as f:
            f.write(report)
            
        return report